﻿using System;
using System.Collections.Generic;
using UnityEngine;

namespace SnakeGame
{
    /// <summary>
    /// 蛇的对象类
    /// </summary>
    public class Snake
    {
        private List<Vector2Int> mBody;

        private Action<Vector2Int> mUpdateMove;
        private Action<Vector2Int, float> mUpdateFace;

        private Vector2Int mLastPos;
        private Vector2Int HeadPos => mBody[0];
        public Vector2Int LastPos => mLastPos;
        private Vector2Int mNextMoveDir = Vector2Int.right;

        public Snake(Action<Vector2Int> updateMove, Action<Vector2Int, float> updateFace)
        {
            mUpdateMove = updateMove;
            mUpdateFace = updateFace;
        }
        /// <summary>
        /// 返回每个身体节点的坐标
        /// </summary>
        public override string ToString()
        {
            string msg = $"SnakeLength:{mBody.Count}\t";
            for (int i = 0; i < mBody.Count; i++) msg += $"p{i}=>{mBody[i].ToString()}  ";
            return msg;
        }
        /// <summary>
        /// 创建蛇身体
        /// </summary>
        public void CreateBody(int x, int y)
        {
            mBody = new List<Vector2Int>(8) { new Vector2Int(y, x) };
        }
        /// <summary>
        /// 长大
        /// </summary>
        public void Bigger() => mBody.Add(mLastPos);
        /// <summary>
        /// 获取移动方向
        /// </summary>
        public void GetMoveDir(int inputX, int inputY)
        {
            if (mBody.Count > 1)
            {
                if (HeadPos.y != mBody[1].y)
                {
                    if (inputX < 0) mNextMoveDir = Vector2Int.left;
                    else if (inputX > 0) mNextMoveDir = Vector2Int.right;
                }
                else if (HeadPos.x != mBody[1].x)
                {
                    if (inputY < 0) mNextMoveDir = Vector2Int.down;
                    else if (inputY > 0) mNextMoveDir = Vector2Int.up;
                }
            }
            else
            {
                if (inputX < 0) mNextMoveDir = Vector2Int.left;
                else if (inputX > 0) mNextMoveDir = Vector2Int.right;
                else if (inputY < 0) mNextMoveDir = Vector2Int.down;
                else if (inputY > 0) mNextMoveDir = Vector2Int.up;
            }
        }
        /// <summary>
        /// 移动方法
        /// </summary>
        public void Move()
        {
            mLastPos = mBody[mBody.Count - 1];
            Vector2Int first; //上一个身体坐标
            for (int i = mBody.Count - 1; i > 0; i--)
            {
                first = mBody[i - 1];
                mUpdateFace(mBody[i], GetMoveAngel(mBody[i], first));
                mBody[i] = first;
            }
            mBody[0] += mNextMoveDir;
            mUpdateFace(HeadPos, GetMoveAngel());
            mUpdateMove(HeadPos);
        }
        /// <summary>
        /// 根据输入方向获取身体节点的旋转角度
        /// </summary>
        private float GetMoveAngel()
        {
            if (mNextMoveDir == Vector2Int.left) return 90;
            if (mNextMoveDir == Vector2Int.right) return -90;
            if (mNextMoveDir == Vector2Int.down) return 180;
            return 0;
        }
        /// <summary>
        /// 根据上下节点的位置获取旋转角度
        /// </summary>
        private float GetMoveAngel(Vector2Int last, Vector2Int previous)
        {
            if (previous.x < last.x) return 90;
            if (previous.x > last.x) return -90;
            if (previous.y < last.y) return 180;
            return 0;
        }
    }
}